package com.quick.system.service.impl;

import java.util.*;

import com.quick.common.constants.UserConstants;
import com.quick.common.core.domain.LoginUser;
import com.quick.common.exception.ServiceException;
import com.quick.common.utils.SecurityUtils;
import com.quick.common.utils.spring.SpringUtils;
import com.quick.framework.service.TokenService;
import com.quick.framework.service.UserLoginService;
import com.quick.system.domain.SysRoleMenu;
import com.quick.system.domain.SysUserRole;
import com.quick.system.mapper.SysRoleMenuMapper;
import com.quick.system.mapper.SysUserRoleMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.quick.system.mapper.SysRoleMapper;
import com.quick.system.domain.SysRole;
import com.quick.system.service.SysRoleService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

/**
 * 角色信息Service业务层处理
 *
 * @Author: 吃素不吃肉
 * @Date: Tue Jul 25 14:14:44 CST 2023
 */
@Service
public class SysRoleServiceImpl implements SysRoleService {
    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;
    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;
    @Autowired
    private TokenService tokenService;

    /**
     * 查询角色信息
     *
     * @param roleId 角色信息主键
     * @return 角色信息
     */
    @Override
    public SysRole selectSysRoleByRoleId(Long roleId) {
        return sysRoleMapper.selectSysRoleByRoleId(roleId);
    }

    /**
     * 查询角色信息列表
     *
     * @param sysRole 角色信息
     * @return 角色信息
     */
    @Override
    public List<SysRole> selectSysRoleList(SysRole sysRole) {
        return sysRoleMapper.selectSysRoleList(sysRole);
    }

    /**
     * 新增角色信息
     *
     * @param sysRole 角色信息
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertSysRole(SysRole sysRole) {
        checkRoleAllowed(sysRole);
        sysRole.setCreateTime(new Date());
        sysRole.setCreateBy(SecurityUtils.getLoginUser().getUsername());
        int row = sysRoleMapper.insertSysRole(sysRole);
        insertRoleMenu(sysRole);
        return row;
    }

    /**
     * 修改角色信息
     *
     * @param sysRole 角色信息
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateSysRole(SysRole sysRole) {
        checkRoleAllowed(sysRole);
        sysRole.setUpdateTime(new Date());
        sysRole.setUpdateBy(SecurityUtils.getLoginUser().getUsername());
        SpringUtils.getBean(this.getClass()).insertRoleMenu(sysRole);
        int row = sysRoleMapper.updateSysRole(sysRole);
        // 更新缓存用户权限
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (Objects.nonNull(loginUser) && !loginUser.admin()) {
            SpringUtils.getBean(UserLoginService.class).setPermission(loginUser);
            tokenService.setLoginUser(loginUser);
        }
        return row;
    }

    public void insertRoleMenu(SysRole sysRole) {
        sysRoleMenuMapper.deleteSysRoleMenuByRoleId(sysRole.getRoleId());
        // 新增用户与角色管理
        List<SysRoleMenu> list = new ArrayList<>();
        List<?> menuIds = (List<?>) sysRole.getParams().get("menuIds");
        if (menuIds != null && menuIds.size() > 0) {
            for (Object menuId : menuIds) {
                SysRoleMenu rm = new SysRoleMenu();
                rm.setRoleId(sysRole.getRoleId());
                rm.setMenuId(Long.valueOf(menuId.toString()));
                list.add(rm);
            }
            if (!CollectionUtils.isEmpty(list)) {
                sysRoleMenuMapper.batchInsertSysRoleMenu(list);
            }
        }
    }

    private void checkRoleAllowed(SysRole sysRole) {
        if (Objects.nonNull(sysRole.getRoleId()) && sysRole.getRoleId().equals(UserConstants.ADMIN_ROLE_ID)) {
            throw new ServiceException("不允许操作超级管理员角色");
        }
        SysRole sysRoleByRoleKey = sysRoleMapper.selectSysRoleByRoleKey(sysRole.getRoleKey());
        SysRole sysRoleByRoleName = sysRoleMapper.selectSysRoleByRoleName(sysRole.getRoleName());
        if (Objects.nonNull(sysRoleByRoleKey)
                && !sysRoleByRoleKey.getRoleId().equals(sysRole.getRoleId())) {
            throw new ServiceException("角色标识已存在！");
        }
        if (Objects.nonNull(sysRoleByRoleName)
                && !sysRoleByRoleName.getRoleId().equals(sysRole.getRoleId())) {
            throw new ServiceException("角色名已存在！");
        }

    }

    /**
     * 批量删除角色信息
     *
     * @param roleIds 需要删除的角色信息主键
     * @return 结果
     */
    @Override
    public int deleteSysRoleByRoleIds(Long[] roleIds) {
        if (sysUserRoleMapper.selectCountByRoleIds(roleIds) > 0) {
            throw new ServiceException("角色已分配给用户，请删除关联用户后重试！");
        }
        return sysRoleMapper.deleteSysRoleByRoleIds(roleIds);
    }

    /**
     * 删除角色信息信息
     *
     * @param roleId 角色信息主键
     * @return 结果
     */
    @Override
    public int deleteSysRoleByRoleId(Long roleId) {
        return sysRoleMapper.deleteSysRoleByRoleId(roleId);
    }

    /**
     * 根据用户id查询角色信息
     *
     * @param userId 用户id
     * @return 角色信息
     */
    @Override
    public Set<String> selectRoleKeyByUserId(Long userId) {
        Set<String> roles = new HashSet<>();
        if (UserConstants.ADMIN_USER_ID.equals(userId)) {
            roles.add(UserConstants.ADMIN_ROLE);
            return roles;
        }
        List<SysRole> sysRoles = sysRoleMapper.selectSysRoleByUserId(userId);
        for (SysRole sysRole : sysRoles) {
            roles.add(sysRole.getRoleKey());
        }
        return roles;
    }

    /**
     * 根据用户id查询角色信息
     *
     * @param userId 用户id
     * @return 角色信息
     */
    @Override
    public List<SysRole> selectSysRoleByUserId(Long userId) {
        return sysRoleMapper.selectSysRoleByUserId(userId);
    }

    /**
     * 修改角色状态
     *
     * @param role 角色信息
     * @return 结果
     */
    @Override
    public int updateRoleStatus(SysRole role) {
        checkRoleAllowed(role);
        SysRole sysRole = new SysRole();
        sysRole.setStatus(role.getStatus());
        sysRole.setRoleId(role.getRoleId());
        sysRole.setUpdateTime(new Date());
        return sysRoleMapper.updateSysRole(sysRole);
    }

    /**
     * 修改数据权限信息
     *
     * @param role 角色信息
     * @return 结果
     */
    @Override
    public int authDataScope(SysRole role) {
        checkRoleAllowed(role);
        SysRole sysRole = new SysRole();
        sysRole.setDataScope(role.getDataScope());
        sysRole.setRoleId(role.getRoleId());
        sysRole.setUpdateTime(new Date());
        return sysRoleMapper.updateSysRole(sysRole);
    }

    /**
     * 取消授权用户角色
     *
     * @param roleId 角色Id
     * @param userId 用户Id
     * @return 结果
     */
    @Override
    public int deleteAuthUser(Long roleId, Long userId) {
        return sysRoleMapper.deleteUserRoleInfo(roleId, userId);
    }

    /**
     * 批量取消授权用户角色
     *
     * @param roleId  角色ID
     * @param userIds 需要取消授权的用户数据ID
     * @return 结果
     */
    @Override
    public int deleteAuthUsers(Long roleId, Long[] userIds) {
        return sysRoleMapper.deleteUserRoleInfos(roleId, userIds);
    }

    /**
     * 批量选择授权用户角色
     *
     * @param roleId  角色ID
     * @param userIds 需要删除的用户数据ID
     * @return 结果
     */
    @Override
    public int insertAuthUsers(Long roleId, Long[] userIds) {
        List<SysUserRole> list = new ArrayList<>();
        for (Long userId : userIds) {
            SysUserRole ur = new SysUserRole();
            ur.setUserId(userId);
            ur.setRoleId(roleId);
            list.add(ur);
        }
        return sysUserRoleMapper.batchUserRole(list);
    }
}
